package com.monlyu.util;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;

import com.monlyu.annotation.ActionAnno;
import com.monlyu.annotation.DefaultAnno;
import com.monlyu.exception.MsgException;
import com.opensymphony.xwork2.ActionInvocation;

/**
 * Action的操作集合
 * 
 * @author monlyu
 * @since 2009-12-15
 */
public class ActionUtil {

	/** 默认的Action的结束符 */
	public final static String ACTINON_END = ".action";
	/** sitemesh默认装饰 */
	public final static int SITEMESH_ALL = 0;
	/** sitemesh仅仅包含body */
	public final static int SITEMESH_BODY = -1;
	/** 返回Ajax数据 */
	public static final int SITEMESH_AJAX = -2;
	
	/** sitemesh的前端标题 */
	public static final int SITEMESH_TITLE = 0;
	
	/** 不显示前端标题 */
	public static final int SITEMESH_TITLE_NONE = 1;
	
	/** 全局的登录字串 ->login */
	public static final String LOGON = "login";
	/** 全局的错误字串 */
	public static final String ERROR = "error";

	/** 分页标签每页显示的数量 */
	public static final int PAGE_SIZE = 10;

	/** common文件的目录 */
	public static final String COMMON_DIR = WebOptUtil.APP_ARGS.getWebRelUrl() + "common/";

	/** 用一个静态变量cacheMap调用之后的annotation */
	private static Map<CacheKey, ActionAnno> annotationCacheMap = new HashMap<CacheKey, ActionAnno>();

	/**
	 * 获取调用过来的Action方法的的Annotaion
	 * 
	 * @return 获取自定的Annotation
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 */
	public static ActionAnno getActionAnno(ActionInvocation ai) throws Exception {
		Class<? extends Object> clazz = ai.getAction().getClass();
		String method = ai.getProxy().getMethod();
		final CacheKey key = new CacheKey(clazz, method);
		final ActionAnno anno = annotationCacheMap.get(key);
		if (anno != null) {
			return anno;
		}
		final Method med = clazz.getMethod(method);
		ActionAnno aa = med.getAnnotation(ActionAnno.class);
		if (aa == null) {
			aa = DefaultAnno.getDefault();
		}
		annotationCacheMap.put(key, aa);
		return aa;
	}

	// =======================================定义一个内部类================================
	private static class CacheKey {
		private final Class<? extends Object> clazz;
		private final String method;

		CacheKey(Class<? extends Object> clazz, String method) {
			this.clazz = clazz;
			this.method = method;
		}

		@Override
		public boolean equals(Object obj) {
			if (obj instanceof CacheKey) {
				CacheKey cacheKey = (CacheKey) obj;
				return HashUtil.equals(cacheKey.clazz, clazz) && HashUtil.equals(cacheKey.method, method);
			}
			return false;
		}

		@Override
		public int hashCode() {
			return HashUtil.hash(clazz, method);
		}
	}

	/**
	 * 需要把错误信息放到拦截器中,让他能显示出来
	 * 
	 * @since 2010-2-23
	 */
	public static String error(ActionInvocation invocation, Throwable e) {
//		Logger logger = Logger.getLogger(invocation.getAction().getClass().getName());
		final HttpServletRequest request = ServletActionContext.getRequest();
		System.out.println("user.dir="+System.getProperty("user.dir"));
		if (e != null) {
//			 PropertyConfigurator.configure(System.getProperty("user.dir")+"\\WebRoot\\WEB-INF\\classes\\log4j.properties");
//		      logger.error(e,e);
			LogFactory.getLog(invocation.getAction().getClass()).error(e, e);
		}
		if (e.getCause() != null && !(e instanceof MsgException)) {
			request.setAttribute("EXCEPTION", e);
		}
		request.setAttribute("ERROR_MSG", e.toString());
		return "error";
	}
}
